home *** CD-ROM | disk | FTP | other *** search
/ Mac Easy 2010 May / Mac Life Ubuntu.iso / casper / filesystem.squashfs / usr / share / pyshared / Onboard / settings.py < prev    next >
Encoding:
Python Source  |  2008-03-03  |  13.2 KB  |  383 lines

  1. #!/usr/bin/python
  2. import gtk
  3. import gtk.glade
  4. import gconf
  5. import gobject
  6.  
  7. from virtkey import virtkey
  8.  
  9. from Onboard.OnboardGtk import OnboardGtk
  10.  
  11. import shutil
  12.  
  13. import utils
  14. from utils import get_install_dir
  15.  
  16. from xml.parsers.expat import ExpatError
  17. from xml.dom import minidom
  18.  
  19. import os
  20. import os.path
  21. import gettext
  22.  
  23. from gettext import gettext as _
  24. #setup gettext
  25. app="onboard-settings"
  26. gettext.textdomain(app)
  27. gettext.bindtextdomain(app)
  28. gtk.glade.textdomain(app)
  29. gtk.glade.bindtextdomain(app)
  30.  
  31. class Settings:
  32.     def __init__(self,mainwin):
  33.  
  34.             
  35.         self.SOK_INSTALL_DIR = get_install_dir()       
  36.         if not self.SOK_INSTALL_DIR:
  37.             print "Onboard not installed properly"
  38.             return
  39.         
  40.         self.gladeXML = gtk.glade.XML(os.path.join(self.SOK_INSTALL_DIR,"data", "settings.glade")) 
  41.         self.window = self.gladeXML.get_widget("settingsWindow")
  42.  
  43.         self.gladeXML.signal_autoconnect({"on_layoutView_released" : self.do_change_layout, 
  44.                 "on_addButton_clicked": self.add_sok,
  45.                 "on_removeButton_clicked": self.cb_removeButton_clicked,
  46.                 "on_macroAddButton_clicked": self.add_macro,
  47.                 "on_closeButton_clicked":self.cb_closeButton_clicked,
  48.                 "on_intervalSpin_value_changed" : self.cb_intervalSpin_value_changed,
  49.                 "on_scanningCheck_toggled" : self.cb_scanningCheck_toggled,
  50.                 "on_closeButton_clicked":gtk.main_quit,
  51.                 "on_personaliseButton_clicked": self.cb_on_personaliseButton_clicked,
  52.                 "on_layoutFolderButton_clicked" : self.cb_layoutFolderButton_clicked,
  53.                 "on_icon_toggled" : self.cb_icon_toggled
  54.                 })
  55.         
  56.         self.layoutView = self.gladeXML.get_widget("layoutView")
  57.         self.macroNumberBox = self.gladeXML.get_widget("macroNumberBox")
  58.         self.macroTextBox = self.gladeXML.get_widget("macroTextBox")
  59.         self.macroDeleteBox = self.gladeXML.get_widget("macroDeleteBox")
  60.         
  61.         self.gconfClient = gconf.client_get_default()
  62.         
  63.  
  64.         self.layoutView.append_column(gtk.TreeViewColumn(None, gtk.CellRendererText(), markup = 0))
  65.                 
  66.  
  67.         self.user_layout_root = "%s/.sok/layouts/" % os.path.expanduser("~")
  68.         if not os.path.exists(self.user_layout_root):
  69.             os.makedirs(self.user_layout_root)
  70.         
  71.         
  72.         self.update_layoutList()
  73.         
  74.         self.on_macros_changed()#Populate the macro list
  75.  
  76.         self.gladeXML.get_widget("icon_toggle").set_active(self.gconfClient.get_bool("/apps/sok/trayicon"))
  77.                     
  78.         
  79.         scanEnabled = self.gconfClient.get_bool("/apps/sok/scanning")
  80.         if scanEnabled:
  81.             self.gladeXML.get_widget("scanningCheck").set_active(True)
  82.         
  83.         scanInterval = self.gconfClient.get_int("/apps/sok/scanning_interval")
  84.         if scanInterval:
  85.             self.gladeXML.get_widget("intervalSpin").set_value(float(scanInterval)/1000)
  86.         
  87.         self.window.show()
  88.             
  89.         self.window.set_keep_above(not mainwin)
  90.         
  91.         self.window.connect("destroy", gtk.main_quit)
  92.  
  93.         
  94.         gtk.main()
  95.  
  96.     
  97.     def on_macros_changed(self,client=None, cxion_id=None, entry=None, user_data=None):
  98.         tempMacroList = self.gconfClient.get_list("/apps/sok/macros",gconf.VALUE_STRING)
  99.         self.macroNumbers = []
  100.         
  101.         for child in self.macroNumberBox.get_children():
  102.             if child.__class__ is gtk.Entry:
  103.                 self.macroNumberBox.remove(child)
  104.         
  105.         for child in self.macroTextBox.get_children():
  106.             if child.__class__ is gtk.Entry:
  107.                 self.macroTextBox.remove(child)
  108.         
  109.         for child in self.macroDeleteBox.get_children():
  110.             if child.__class__ is gtk.Button:
  111.                 self.macroDeleteBox.remove(child)
  112.         
  113.         for n in range(len(tempMacroList)):
  114.             macroStr = tempMacroList[n]
  115.             if macroStr:
  116.                 self.macroNumbers.append(n)
  117.                 
  118.                 numberEntry = gtk.Entry()
  119.                 numberEntry.set_text(str(n))
  120.                 numberEntry.connect("activate",self.cb_macro_numberEntry_activate,n)
  121.                 numberEntry.set_size_request(5, 30)
  122.                 self.macroNumberBox.pack_start(numberEntry,False,False,5)
  123.                 numberEntry.show()
  124.  
  125.                 textEntry = gtk.Entry()
  126.                 textEntry.set_text(macroStr)
  127.                 textEntry.connect("activate",self.cb_macro_textEntry_activate,n)
  128.                 textEntry.set_size_request(-1, 30)
  129.                 self.macroTextBox.pack_start(textEntry,False,False,5)
  130.                 textEntry.show()
  131.                 
  132.                 deleteButton = gtk.Button(stock=gtk.STOCK_DELETE)
  133.                 deleteButton.connect("clicked",self.cb_macro_deleteButton_clicked,n)
  134.                 self.macroDeleteBox.pack_start(deleteButton,False,False,5)
  135.                 deleteButton.show()
  136.                 
  137.  
  138.     def cb_macro_numberEntry_activate(self,widget,currentNumber):
  139.         
  140.         newNo = int(widget.get_text())
  141.         
  142.         if not newNo in self.macroNumbers:
  143.             li = self.gconfClient.get_list("/apps/sok/macros",gconf.VALUE_STRING)
  144.             
  145.             if newNo > (len(li) - 1):
  146.                 for n in range(len(li) - (newNo - 1)):      
  147.                     li.append("")
  148.             text = li[currentNumber]
  149.  
  150.             li[currentNumber] = ""
  151.             li[newNo] = text
  152.             
  153.             self.gconfClient.set_list("/apps/sok/macros",gconf.VALUE_STRING,li)
  154.             
  155.             self.on_macros_changed()
  156.         else:
  157.             dialog = gtk.MessageDialog(self.window,type=gtk.MESSAGE_WARNING,buttons=gtk.BUTTONS_OK,message_format=_("Snippet already assigned to this number"))
  158.             dialog.run()
  159.             widget.set_text(str(currentNumber))
  160.             dialog.destroy()
  161.             
  162.             
  163.  
  164.     def cb_macro_textEntry_activate(self,widget,currentNumber):
  165.         li = self.gconfClient.get_list("/apps/sok/macros",gconf.VALUE_STRING)       
  166.         
  167.         li[currentNumber] = widget.get_text()
  168.         
  169.         self.gconfClient.set_list("/apps/sok/macros",gconf.VALUE_STRING,li)
  170.         
  171.         self.on_macros_changed()
  172.         
  173.         
  174.         
  175.  
  176.     def cb_macro_deleteButton_clicked(self,widget,currentNumber):
  177.         li = self.gconfClient.get_list("/apps/sok/macros",gconf.VALUE_STRING)       
  178.         
  179.         li[currentNumber] = ""
  180.         
  181.         self.gconfClient.set_list("/apps/sok/macros",gconf.VALUE_STRING,li)
  182.         
  183.         self.on_macros_changed()
  184.  
  185.     def cb_icon_toggled(self,widget):
  186.         self.gconfClient.set_bool("/apps/sok/trayicon",widget.get_active())
  187.  
  188.     def open_user_layout_dir(self):
  189.         if os.path.exists('/usr/bin/nautilus'):
  190.             os.system(("nautilus --no-desktop %s" %self.user_layout_root))
  191.         elif os.path.exists('/usr/bin/thunar'):
  192.             os.system(("thunar %s" %self.user_layout_root))
  193.         else:
  194.             print _("No file manager to open layout folder")
  195.             
  196.     def cb_layoutFolderButton_clicked(self,widget):
  197.         self.open_user_layout_dir()
  198.  
  199.     def cb_on_personaliseButton_clicked(self, widget):
  200.         dialog = MacroDialog(self.window, 
  201.                             _("Enter name for personalised layout")) #recycling
  202.         dialog.show_all()
  203.         response = dialog.run()
  204.         if response == gtk.RESPONSE_OK:
  205.             text = dialog.macroEntry.get_text()
  206.             s = OnboardGtk(False)
  207.             utils.create_layout_XML(text, virtkey(), s)
  208.             s.clean()
  209.             self.update_layoutList()
  210.             self.open_user_layout_dir()
  211.  
  212.         dialog.destroy()
  213.         
  214.     def cb_scanningCheck_toggled(self,widget):
  215.         self.gconfClient.set_bool("/apps/sok/scanning",widget.get_active())
  216.     
  217.     def cb_intervalSpin_value_changed(self,widget):
  218.         self.gconfClient.set_int("/apps/sok/scanning_interval", int(widget.get_value()*1000))
  219.     
  220.     def cb_closeButton_clicked(self, widget):
  221.         self.window.destroy()
  222.  
  223.     def update_layoutList(self):    
  224.         self.layoutList = gtk.ListStore(str,str)
  225.         self.layoutView.set_model(self.layoutList)
  226.         
  227.         #it = self.layoutList.append(("Default", ""))
  228.         #self.layoutView.get_selection().select_iter(it)
  229.         self.get_soks(os.path.join(self.SOK_INSTALL_DIR,"layouts"))
  230.         self.get_soks(self.user_layout_root)
  231.         
  232.     
  233.     def cb_selected_layout_changed(self):
  234.         self.get_soks(self.user_layout_root)
  235.  
  236.     def cb_macroList_drag_drop(self, widget, event,thing1,thing2,thing3):
  237.         gobject.idle_add(self.macroList_changed)#To make sure gtk has finished changing the value of macroList before updating gconf.
  238.         
  239.  
  240.     def add_macro(self, event):
  241.  
  242.         dialog = MacroDialog(self.window,_("Enter text for snippet"))
  243.  
  244.         dialog.show_all()
  245.         response = dialog.run()
  246.         if response == gtk.RESPONSE_OK:
  247.             text = dialog.macroEntry.get_text()
  248.             
  249.             l = self.gconfClient.get_list("/apps/sok/macros",gconf.VALUE_STRING)
  250.             
  251.             if self.macroNumbers:
  252.                 if len(l) <= (self.macroNumbers[-1] +1):
  253.                     l.append(text)
  254.                 else:
  255.                     l[self.macroNumbers[-1] + 1] = text
  256.             else:
  257.                 l.append(text)
  258.             self.gconfClient.set_list("/apps/sok/macros",gconf.VALUE_STRING, l)
  259.             
  260.         dialog.destroy()
  261.         
  262.         self.on_macros_changed()        
  263.         
  264.  
  265.     
  266.     
  267.     def add_sok(self, event):#todo filtering
  268.         chooser = gtk.FileChooserDialog(title=None,action=gtk.FILE_CHOOSER_ACTION_OPEN,
  269.                                       buttons=(gtk.STOCK_CANCEL,gtk.RESPONSE_CANCEL,gtk.STOCK_OPEN,gtk.RESPONSE_OK))
  270.         filterer = gtk.FileFilter()
  271.         filterer.add_pattern("*.sok")
  272.         chooser.add_filter(filterer)
  273.         response = chooser.run()
  274.         if response == gtk.RESPONSE_OK:
  275.             filename = chooser.get_filename()
  276.                 
  277.  
  278.             f = open(filename)
  279.             sokdoc = minidom.parse(f).documentElement
  280.             for p in sokdoc.getElementsByTagName("pane"):
  281.                 fn = p.attributes['filename'].value
  282.                 
  283.                 shutil.copyfile("%s/%s" % (os.path.dirname(filename), fn), "%s%s" % (self.user_layout_root, fn)) 
  284.             
  285.  
  286.             shutil.copyfile(filename,"%s%s" % (self.user_layout_root, os.path.basename(filename)))
  287.  
  288.             self.update_layoutList()
  289.         chooser.destroy()
  290.         
  291.  
  292.     def cb_removeButton_clicked(self, event):
  293.         filename = self.layoutList.get_value(self.layoutView.get_selection().get_selected()[1],1)
  294.  
  295.         f = open(filename)
  296.         sokdoc = minidom.parse(f).documentElement
  297.         f.close()
  298.         
  299.         os.remove(filename)
  300.  
  301.         for p in sokdoc.getElementsByTagName("pane"):
  302.             os.remove("%s/%s" % (os.path.dirname(filename), p.attributes['filename'].value))#todo get sok to deal with not having a layout.
  303.         self.gconfClient.set_string("/apps/sok/layout_filename", '')
  304.         self.update_layoutList()
  305.         
  306.  
  307.  
  308.     def get_soks(self, path):
  309.         
  310.         files = os.listdir(path)
  311.             
  312.         soks = []
  313.         for f in files:
  314.             if f[-4:] == ".sok":
  315.                 filename = "%s/%s" % (path,f)
  316.                 file_object = open(filename)
  317.                 try:
  318.                     sokdoc = minidom.parse(file_object).documentElement
  319.  
  320.                     if os.access(filename,os.W_OK):
  321.                         it = self.layoutList.append(("<i>%s</i>" 
  322.                             % sokdoc.attributes["id"].value, filename))
  323.                     else:
  324.                         it = self.layoutList.append((
  325.                             sokdoc.attributes["id"].value, filename))
  326.                 
  327.                     if filename == self.gconfClient.get_string("/apps/sok/layout_filename"):
  328.                         self.layoutView.get_selection().select_iter(it)
  329.                 except ExpatError,(strerror):
  330.                     print "XML in %s %s" % (filename, strerror)
  331.                 except KeyError,(strerror):
  332.                     print "key %s required in %s" % (strerror,filename)
  333.                 
  334.                 file_object.close()
  335.                 
  336.  
  337.             
  338.  
  339.  
  340.  
  341.     def find_soks(self, path):
  342.         #files = os.listdir("%s/.sok/layouts" % os.path.expanduser("~"))
  343.         files = os.listdir(path)
  344.         soks = []
  345.         for f in files:
  346.             if f[-4:] == ".sok":
  347.                 soks.append(f)
  348.         return soks
  349.  
  350.  
  351.  
  352.     def do_change_layout(self,widget,event):
  353.         
  354.         
  355.         filename = self.layoutList.get_value(widget.get_selection().get_selected()[1],1)
  356.         
  357.         
  358.         
  359.         self.gconfClient.set_string("/apps/sok/layout_filename", filename)
  360.     
  361.     
  362.  
  363.     
  364. class MacroDialog(gtk.MessageDialog):
  365.     def __init__(self,parent,message):
  366.         gtk.MessageDialog.__init__(self,parent,gtk.MESSAGE_QUESTION)
  367.         self.add_buttons(gtk.STOCK_OK,gtk.RESPONSE_OK,
  368.                     gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL)
  369.         self.macroEntry = gtk.Entry()
  370.         self.macroEntry.connect("activate", self.cb_macroEntry_activated)
  371.         self.vbox.pack_end(self.macroEntry)
  372.         self.set_markup(message)
  373.  
  374.     def cb_macroEntry_activated(self, event):
  375.         self.response(gtk.RESPONSE_OK)
  376.  
  377.             
  378.     
  379. if __name__=='__main__':
  380.     
  381.     s = Settings(True)
  382. #    gtk.main()
  383.